package com.telecom.common.utils;

import com.telecom.aspect.interceptor.TokenPayload;
import com.telecom.common.convention.errorcode.BaseErrorCode;
import com.telecom.common.convention.exception.ClientException;
import com.telecom.common.convention.exception.ServiceException;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * JWT工具类
 */
@Slf4j
@Component
public class JwtUtils {
    
    // JWT密钥字符串 - 生产环境请使用配置文件
    @Value(value = "${jwt.secret-key}")
    private String SECRET_KEY;
    
    // Token过期时间 - 24小时
    @Value(value = "${jwt.expiration}")
    private long EXPIRATION_TIME;

    
    /**
     * 生成JWT Token
     * 
     * @param userId 用户ID
     * @param username 用户名
     * @param role 用户角色(0:USER 1:ADMIN)
     * @return JWT Token
     */
    public String generateToken(Long userId, String username, Integer role) {
        // 参数验证
        if (userId == null) {
            log.error("生成Token失败：用户ID不能为空");
            throw new ServiceException("用户ID不能为空", BaseErrorCode.CLIENT_ERROR);
        }
        
        if (username == null || username.trim().isEmpty()) {
            log.error("生成Token失败：用户名不能为空，userId: {}", userId);
            throw new ServiceException("用户名不能为空", BaseErrorCode.CLIENT_ERROR);
        }
        
        if (role == null || (role != 0 && role != 1)) {
            log.error("生成Token失败：角色值无效，userId: {}, role: {}", userId, role);
            throw new ServiceException("角色值无效", BaseErrorCode.CLIENT_ERROR);
        }
        
        try {
            Date now = new Date();
            Date expiration = new Date(now.getTime() + EXPIRATION_TIME);
            
            String token = Jwts.builder()
                .setSubject(String.valueOf(userId))
                .claim("userId", userId)
                .claim("username", username.trim())
                .claim("role", role)
                .setIssuedAt(now)
                .setExpiration(expiration)
                .signWith(SignatureAlgorithm.HS256, SECRET_KEY)
                .compact();
                
            log.debug("JWT Token生成成功，userId: {}, role: {}, expiration: {}", userId, role, expiration);
            return token;
            
        } catch (Exception e) {
            log.error("生成JWT失败，userId: {}, username: {}, role: {}", userId, username, role, e);
            throw new ServiceException("生成Token失败", BaseErrorCode.SERVICE_ERROR);
        }
    }
    
    /**
     * 解析JWT Token获取用户信息
     * 
     * @param token JWT Token
     * @return TokenPayload 包含用户信息的载荷对象
     */
    public TokenPayload parseUser(String token) {

        TokenPayload payload = new TokenPayload();

        try
        {
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(SECRET_KEY)
                    .build()
                    .parseClaimsJws(token)
                    .getBody();

            // 构建TokenPayload对象

            payload.setUserId(claims.get("userId", Long.class));
            payload.setRole(claims.get("role", Integer.class));
            payload.setUsername(claims.get("username", String.class));
            payload.setExpiredAt(claims.getExpiration());
            payload.setIssuedAt(claims.getIssuedAt());
        }
        catch (Exception e)
        {
            throw new ServiceException("解析token出错", BaseErrorCode.SERVICE_ERROR);
        }

        // 额外的数据有效性检查
        if (payload.getUserId() == null) {
            log.error("Token中缺少userId信息");
            throw new ClientException("Token格式错误：缺少用户ID", BaseErrorCode.UNAUTHORIZED);
        }

        if (payload.getRole() == null) {
            log.error("Token中缺少role信息，userId: {}", payload.getUserId());
            throw new ClientException("Token格式错误：缺少角色信息", BaseErrorCode.UNAUTHORIZED);
        }

        // 双重检查过期时间（虽然JWT库已经检查，但额外验证）
        Date now = new Date();
        if (payload.getExpiredAt() != null && payload.getExpiredAt().before(now)) {
            log.warn("Token已过期，userId: {}, expiredAt: {}", payload.getUserId(), payload.getExpiredAt());
            throw new ClientException("Token已过期", BaseErrorCode.UNAUTHORIZED);
        }

        log.debug("JWT Token解析成功，userId: {}, role: {}", payload.getUserId(), payload.getRole());
        return payload;
    }
    


}